package com.chengcang.admin.modules.busi.controller;

import com.chengcang.admin.common.annotation.LogOperation;
import com.chengcang.admin.common.utils.ExcelUtils;
import com.chengcang.admin.modules.busi.dto.BusiDemandDTO;
import com.chengcang.admin.modules.busi.dto.BusiDemandDetailDTO;
import com.chengcang.admin.modules.busi.dto.TransferOrderDTO;
import com.chengcang.admin.modules.busi.entity.BusiTaxEntity;
import com.chengcang.admin.modules.busi.excel.BusiDemandExcel;
import com.chengcang.admin.modules.busi.service.BusiDemandService;
import com.chengcang.admin.modules.security.user.SecurityUser;
import com.chengcang.admin.modules.sys.dto.SysDictDataDTO;
import com.chengcang.admin.modules.sys.dto.SysTenantDTO;
import com.chengcang.admin.modules.sys.service.SysProductService;
import com.chengcang.common.constant.Constant;
import com.chengcang.common.page.PageData;
import com.chengcang.common.utils.Result;
import com.chengcang.common.validator.AssertUtils;
import com.chengcang.common.validator.ValidatorUtils;
import com.chengcang.common.validator.group.AddGroup;
import com.chengcang.common.validator.group.DefaultGroup;
import com.chengcang.common.validator.group.UpdateGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;


/**
 * 需求前端控制器
 *
 * @author bibajin
 * @since 1.0.0 2023-01-10
 */
@RestController
@RequestMapping("busi/demand")
@Api(tags = "需求管理")
public class BusiDemandController {
    @Autowired
    private BusiDemandService busiDemandService;

    @Autowired
    private SysProductService sysProductService;

    @GetMapping("page")
    @ApiOperation("分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "demandNo", value = "需求编号", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "demandStatus", value = "需求状态", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "payStatus", value = "支付状态", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "tenantType", value = "履约客户", paramType = "query", required = false, dataType = "Long"),
            @ApiImplicitParam(name = "dataSource", value = "需求来源", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = false, dataType = "Date"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = false, dataType = "Date"),
            @ApiImplicitParam(name = Constant.PAGE, value = "当前页码，从1开始", paramType = "query", required = true, dataType = "int"),
            @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", required = true, dataType = "int"),
            @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = Constant.ORDER, value = "排序方式，可选值(asc、desc)", paramType = "query", dataType = "String")
    })
    @RequiresPermissions("busi:demand:page")
    public Result<PageData<BusiDemandDTO>> page(@ApiIgnore @RequestParam Map<String, Object> params) {
        PageData<BusiDemandDTO> page = busiDemandService.page(params);

        return new Result<PageData<BusiDemandDTO>>().ok(page);
    }

    @GetMapping("appoint")
    @ApiOperation("履约")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "demandNo", value = "需求编号", paramType = "query", required = false, dataType = "String"),
            @ApiImplicitParam(name = "demandStatus", value = "需求状态", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "payStatus", value = "支付状态", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "tenantType", value = "履约客户", paramType = "query", required = false, dataType = "Long"),
            @ApiImplicitParam(name = "dataSource", value = "需求来源", paramType = "query", required = false, dataType = "int"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", required = false, dataType = "Date"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", required = false, dataType = "Date"),
            @ApiImplicitParam(name = Constant.PAGE, value = "当前页码，从1开始", paramType = "query", required = true, dataType = "int"),
            @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", required = true, dataType = "int"),
            @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = Constant.ORDER, value = "排序方式，可选值(asc、desc)", paramType = "query", dataType = "String")
    })
    @RequiresPermissions("busi:demand:appoint")
    public Result<PageData<BusiDemandDTO>> appoint(@ApiIgnore @RequestParam Map<String, Object> params) {
        PageData<BusiDemandDTO> page = busiDemandService.appoint(params);

        return new Result<PageData<BusiDemandDTO>>().ok(page);
    }


    @GetMapping("{id}")
    @ApiOperation("信息")
    @RequiresPermissions("busi:demand:info")
    public Result<BusiDemandDetailDTO> get(@PathVariable("id") Long id) {
        BusiDemandDetailDTO data = busiDemandService.getDeamndDetailByTenantId(id);

        return new Result<BusiDemandDetailDTO>().ok(data);
    }

    @PutMapping
    @ApiOperation("修改")
    @LogOperation("修改")
    @RequiresPermissions("busi:demand:update")
    public Result update(@RequestBody BusiDemandDTO dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);

        busiDemandService.update(dto);

        return new Result();
    }

    @DeleteMapping
    @ApiOperation("删除")
    @LogOperation("删除")
    @RequiresPermissions("busi:demand:delete")
    public Result delete(@RequestBody Long[] ids) {
        //效验数据
        AssertUtils.isArrayEmpty(ids, "id");

        busiDemandService.delete(ids);

        return new Result();
    }

    @GetMapping("export")
    @ApiOperation("导出")
    @LogOperation("导出")
    @RequiresPermissions("busi:demand:export")
    public void export(@ApiIgnore @RequestParam Map<String, Object> params, HttpServletResponse response) throws Exception {
        List<BusiDemandDTO> list = busiDemandService.list(params);

        ExcelUtils.exportExcelToTarget(response, null, list, BusiDemandExcel.class);
    }

    /**
     * 新增需求
     *
     * @param dto
     * @return
     */
    @PostMapping("saveDemand")
    @ApiOperation("新增需求单")
    @LogOperation("新增需求单")
    @RequiresPermissions("busi:demand:save")
    public Result saveDemand(@RequestBody @Valid BusiDemandDTO dto) {
        //效验数据
        ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);

        busiDemandService.saveDemand(dto);

        return new Result();
    }

    /**
     * 新增需求时查询发票信息和地址信息的接口
     *
     * @param tenantId 发送需求方ID
     * @return
     */
    @GetMapping("getInvoiceAndAddress")
    @ApiOperation("新增需求：查询发票信息和地址信息")
    public Result<BusiDemandDetailDTO> getInvoiceAndAddress(@RequestParam(required = false) Long tenantId) {
        return busiDemandService.getInvoiceAndAddress(tenantId);
    }

    /**
     * 根据商品id查询商品计量单位
     *
     * @param
     * @return
     */
    @GetMapping("getProductInfoByProductId")
    @ApiOperation("根据商品id查询商品计量单位")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "productId", value = "商品id", paramType = "query", required = true, dataType = "Long")
    })
    public Result<List<SysDictDataDTO>> getProductInfoByProductId(Long productId) {
        List<SysDictDataDTO> specList = sysProductService.getSpec(productId);
        return new Result<List<SysDictDataDTO>>().ok(specList);
    }

    /**
     * 根据供应商名称模糊查询
     *
     * @param
     * @return
     */
    @GetMapping("getTenantByTenantName")
    @ApiOperation("根据供应商名称模糊查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "客户名称", paramType = "query", required = false, dataType = "String")
    })
    @RequiresPermissions("busi:demand:tenant")
    public Result<List<SysTenantDTO>> getTenantByTenantName(@RequestParam(required = false) String name) {
        return new Result().ok(busiDemandService.getTenantByTenantName(name));
    }

    /**
     * 转单
     * @param transferOrderDto
     * @return
     */
    @PostMapping("transferDemandOrder")
    @ApiOperation("转单")
    @RequiresPermissions("busi:demand:transfer")
    public Result transferDemandOrder(@RequestBody  @Valid TransferOrderDTO transferOrderDto) {
        busiDemandService.transferDemandOrder(transferOrderDto);
        return new Result();
    }

    /**
     * 关闭需求单
     */
    @GetMapping("closeDemand")
    @ApiOperation("关单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "需求单id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "reason", value = "关闭原因", required = true, dataType = "String")
    })
//    @RequiresPermissions("busi:demand:closeDemand")
    public Result closeDemand(@RequestParam("id") Long id, @RequestParam("reason") String reason) {
        busiDemandService.closeDemand(id, reason);
        return new Result();
    }

    @GetMapping("tax")
    @ApiOperation("税费计算")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "price",value = "单价",required = true,dataType = "String"),
            @ApiImplicitParam(name = "amount",value = "数量",required = true,dataType = "String")
    })
    public Result tax(@RequestParam("price") String price,@RequestParam("amount") String amount) {
        BigDecimal priceDecimal = new BigDecimal(price);
        BigDecimal amountDecimal = new BigDecimal(amount);

        //计算税金额
        //卖家收款金额 单价乘以数量
        BigDecimal totalPrice = priceDecimal.multiply(amountDecimal).setScale(2, RoundingMode.HALF_UP);
        BigDecimal sellerReceivePrice = priceDecimal.multiply(amountDecimal).setScale(2,RoundingMode.HALF_UP);
        //税率
        BigDecimal taxRate = new BigDecimal("0.001");
        //服务费率
        BigDecimal serviceRate = new BigDecimal("0.001");
        // 1
        BigDecimal unit1 = new BigDecimal(1);

        //不含增值税金额
        BigDecimal noVatPrice = sellerReceivePrice.multiply((serviceRate.add(unit1))).setScale(2,RoundingMode.UP);
        //增值税
        BigDecimal vat = sellerReceivePrice.multiply(taxRate.divide(
                unit1.subtract(taxRate), 6,RoundingMode.UP)).setScale(2,RoundingMode.UP);
        //合同总价
        BigDecimal contractTotalPrice = sellerReceivePrice
                .multiply((unit1.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP);
        //平台代收税费
        BigDecimal platformTakeTaxPrice = sellerReceivePrice.multiply(
                (taxRate.divide(unit1.subtract(taxRate),6, RoundingMode.UP))
                        .add(serviceRate).setScale(6,RoundingMode.UP)).setScale(2,RoundingMode.UP);
        BusiTaxEntity busiTaxEntity = new BusiTaxEntity();
        DecimalFormat df = new DecimalFormat("#,##0.00");
        busiTaxEntity.setTotalPrice(df.format(totalPrice));
        busiTaxEntity.setSellerReceivePrice(df.format(sellerReceivePrice));
        busiTaxEntity.setVat(df.format(vat));
        busiTaxEntity.setNoVatPrice(df.format(noVatPrice));
        busiTaxEntity.setContractTotalPrice(df.format(contractTotalPrice));
        busiTaxEntity.setPlatformTakeTaxPrice(df.format(platformTakeTaxPrice));
        return new Result().ok(busiTaxEntity);
    }
}
